// ts运行
// tsc --init 创建tsconfig.json
// 方式1. npm install -g typescript, 生成js文件并运行, tsc --lib es2015,dom xxx.ts, node xxx.js
// 方式2. npm install -g ts-node, 自动编译并运行, ts-node xxx.ts

type _Worker = {
    callable: Function,
    resolve: (value: unknown) => void,
    reject: (reason?: any) => void,
} | undefined;
interface IWorker {
    runWorker(): Promise<void>;
    exit(w: IWorker): void;
}

class TaskPool {
    private coreSize: number;
    private workers: Set<IWorker>; 
    private workQueue: Array<_Worker>;

    constructor(coreSize: number) {
        this.coreSize = coreSize;
        this.workers = new Set<IWorker>();
        this.workQueue = new Array<_Worker>();
    }

    submit(callable: Function) {
        return new Promise((resolve, reject) => {
            if (this.workers.size < this.coreSize) {
                // 创建新worker并执行
                this.addWorker({callable, resolve, reject});
                return;
            }
            // 加入到队列
            let bb = {callable, resolve, reject};
            this.workQueue.push({callable, resolve, reject});
        });
    }

    private addWorker(future: _Worker) {
        let w = new TaskWorker(future, this);
        w.exit = (_w) => this.processWorkerExit(_w);
        this.workers.add(w);
        w.runWorker();
    }

    private processWorkerExit(w: IWorker) {
        this.workers.delete(w);
    }

    public getTask(): _Worker {
        return this.workQueue.shift();
    }
}

class TaskWorker implements IWorker {
    private first: _Worker = undefined;
    private pool: TaskPool;
    constructor(first: _Worker, pool: TaskPool) {
        this.first = first;
        this.pool = pool;
    }

    public async runWorker() {
        let task = this.first;
        this.first = undefined;
        while (task != undefined 
            || (task = this.pool.getTask()) != undefined) {
                try {
                    task.resolve(task.callable());
                } catch (error) {
                    task.reject(error);
                } finally {
                    task = undefined;
                }
        }
        this.exit(this as IWorker);
    }

    public exit(self: IWorker) {}
}

console.log('Hello TypeScript');
const pool = new TaskPool(3);
pool.submit(()=>console.log('res',2*9));
const params = new URLSearchParams();
params.append('str', 'hello');
params.append('str2', 'TypeScript');
fetch('http://127.0.0.1:13080/base/test_one', {
    method: 'POST',
    body: params,
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
    },
}).then(resp=>console.info(resp));